#ifndef TRANSFORM_H
#define TRANSFORM_H

#include <GameGlobals.h>

struct Transform
{
	float scale;
	float angle;
	mat2 rot;
	vec2 loc;
	float rot_array[4];

	void UpdateRotArray() {
		rot_array[0] = rot.ex.x; rot_array[1] = rot.ex.y;
		rot_array[2] = rot.ey.x; rot_array[3] = rot.ey.y;
	}

	inline float GetAngleRadians() { return angle * Global::PI / 180.0f; }

	Transform():scale(1.0f),angle(0){ 
		rot.SetIdentity(); loc.Set(0,0); 
		UpdateRotArray();
	}

	inline void SyncRotateToDirection( const vec2 dir )
	{
		//find angle between up vector and dir, then use SetRotate with that angle
		vec2 up(0,1);
		float dot_result = b2Dot( up, dir );
		float length = dir.Length();
		float radian_angle = acos( dot_result / length );
		SetRotateRadian( radian_angle );
	}

	inline vec2 GetDir()
	{
		vec2 up(0,1);
		vec2 out = rot.Solve(up);
		return out;
	}

	inline void SetRotateRadian(float r)
	{
		const float ANGLE = r *  180.0f / Global::PI;
		angle = ANGLE;
		if( angle < 0.0f ) angle += 360.0f;
		if( angle > 360.0f ) angle -= 360.0f;

		float cosx = cos( r );
		float sinx = sin( r );
		rot.Set( vec2( cosx, sinx ), vec2( -sinx, cosx ) );
		UpdateRotArray();
	}

	inline void SetRotate(float theta)
	{
		if( theta < 0.0f ) theta += 360.0f;
		if( theta > 360.0f ) theta -= 360.0f;

		angle = theta;
		const float RADIANS = angle * Global::PI / 180.0f;
		float cosx = cos( RADIANS );
		float sinx = sin( RADIANS );
		rot.Set( vec2( cosx, sinx ), vec2( -sinx, cosx ) );
		UpdateRotArray();
	}

	inline void Rotate(const float theta)
	{
		angle += theta;
		if( angle < 0.0f ) angle += 360.0f;
		if( angle > 360.0f ) angle -= 360.0f;

		const float RADIANS = angle * Global::PI / 180.0f;
		float cosx = cos( RADIANS );
		float sinx = sin( RADIANS );
		rot.Set( vec2( cosx, sinx ), vec2( -sinx, cosx ) );
		UpdateRotArray();
	}
};


#endif